﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 *
 **/

using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Windows.Input;
using ICSharpCode.AvalonEdit.Highlighting;
using Peter.Common;
using Peter.Common.MainMenu;
using Peter.Properties;

namespace Peter.Logic
{
   /// <summary>
   /// Represents the menu items in Peter.
   /// </summary>
   public class MenuItems
   {
      private static readonly PeterMainMenuItem s_RecentFiles = new PeterMainMenuItem
      {
         Icon = MainMenuIcon.Importfile,
         Title = "Recent Files"
      };

      #region Headers

      /// <summary>
      /// Gets the home header.
      /// </summary>
      [Export (typeof (IMainMenuHeader))]
      public IMainMenuHeader HomeMenuHeader
      {
         get
         {
            return new PeterMainMenuHeader ("HOME")
            {
               Priority = 0,
               Icon = MainMenuIcon.Home
            };
         }
      }

      /// <summary>
      /// Gets the view header.
      /// </summary>
      [Export (typeof (IMainMenuHeader))]
      public IMainMenuHeader ViewMenuHeader
      {
         get
         {
            return new PeterMainMenuHeader ("VIEW")
            {
               Priority = 1,
               Icon = MainMenuIcon.Windows
            };
         }
      }

      /// <summary>
      /// Gets the view header.
      /// </summary>
      [Export (typeof (IMainMenuHeader))]
      public IMainMenuHeader ToolsMenuHeader
      {
         get
         {
            return new PeterMainMenuHeader ("TOOLS")
            {
               Priority = 1,
               Icon = MainMenuIcon.Tools
            };
         }
      }
      
      /// <summary>
      /// Gets the source header.
      /// </summary>
      [Export (typeof (IMainMenuHeader))]
      public IMainMenuHeader SourceMenuHeader
      {
         get
         {
            return new PeterMainMenuHeader ("SOURCE")
            {
               Priority = 1,
               Icon = MainMenuIcon.Opensource
            };
         }
      }

      /*/// <summary>
      /// Gets the test header.
      /// </summary>
      [Export (typeof (IMainMenuHeader))]
      public IMainMenuHeader TestMenuHeader
      {
         get
         {
            return new PeterMainMenuHeader ("TEST")
            {
               Priority = 1,
               Icon = MainMenuIcon.Notestasks
            };
         }
      }*/
      
      #endregion

      #region Home

      #region Home Drop Down Menu Items

      /// <summary>
      /// Gets the save as menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem SaveAsMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 0,
               HeaderName = "home",
               IsHeaderMenuItem = true,
               Title = "Save As...",
               Command = ApplicationCommands.SaveAs,
               ToolTip = "Saves the active content in a new file (Ctrl+Alt+S)",
               Icon = MainMenuIcon.SaveFloppy
            };
         }
      }

      /// <summary>
      /// Gets the save all menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem SaveAllMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 1,
               HeaderName = "home",
               IsHeaderMenuItem = true,
               Title = "Save All",
               Command = PeterApplicationCommands.SaveAll,
               ToolTip = "Saves all content (Ctrl+Shift+S)",
               Icon = MainMenuIcon.Savetodrive
            };
         }
      }

      /// <summary>
      /// Gets the exit menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem ExitMenuSeparator
      {
         get
         {
            return new MainMenuSeperator
            {
               Priority = 98,
               HeaderName = "home",
               IsHeaderMenuItem = true,
            };
         }
      }

      /// <summary>
      /// Gets the exit menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem ExitMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 99,
               HeaderName = "home",
               IsHeaderMenuItem = true,
               Title = "Exit",
               Command = ApplicationCommands.Close,
               Icon = MainMenuIcon.Exit,
               ToolTip = "Exit Peter (Alt+F4)"
            };
         }
      }

      #endregion

      /// <summary>
      /// Gets the new document menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem NewDocumentMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 0,
               Command = ApplicationCommands.New,
               Icon = MainMenuIcon.Createfile,
               ToolTip = "New File (Ctrl+N)",
               Children =
                  {
                     new PeterMainMenuItem
                        {
                           Command = PeterApplicationCommands.NewProject,
                           Icon = MainMenuIcon.News,
                           Title = "New Project",
                           ToolTip = "New Project (Ctrl+Alt+N)"
                        }
                  }
            };
         }
      }

      /// <summary>
      /// Gets the open document menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem OpenMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 10,
               Command = ApplicationCommands.Open,
               Icon = MainMenuIcon.Openfolderalt,
               ToolTip = "Open file (Ctrl+O)",
               Children =
                  {
                     new PeterMainMenuItem
                        {
                           Command = PeterApplicationCommands.OpenProject,
                           Icon = MainMenuIcon.FolderOpen,
                           Title = "Open Project",
                           ToolTip = "Open Project (Ctrl+Alt+O)"
                        },
                     new MainMenuSeperator (),
                     s_RecentFiles
                  }
            };
         }
      }

      /// <summary>
      /// Gets the save document menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem SaveMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 20,
               Command = ApplicationCommands.Save,
               ToolTip = "Saves the active content (Ctrl+S)",
               Icon = MainMenuIcon.SaveFloppy
            };
         }
      }

      /// <summary>
      /// Gets the cut menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem CutMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 100,
               Command = ApplicationCommands.Cut,
               Icon = MainMenuIcon.CutScissors,
               ToolTip = "Cut (Ctrl+X)"
            };
         }
      }

      /// <summary>
      /// Gets the copy menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem CopyMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 101,
               Command = ApplicationCommands.Copy,
               Icon = MainMenuIcon.Copy,
               ToolTip = "Copy (Ctrl+C)"
            };
         }
      }

      /// <summary>
      /// Gets the paste menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem PasteMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 102,
               Command = ApplicationCommands.Paste,
               Icon = MainMenuIcon.ClipboardPaste,
               ToolTip = "Paste (Ctrl+V)"
            };
         }
      }

      /// <summary>
      /// Gets the undo menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem UndoMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 200,
               Command = ApplicationCommands.Undo,
               Icon = MainMenuIcon.Undo,
               ToolTip = "Undo (Ctrl+Z)"
            };
         }
      }

      /// <summary>
      /// Gets the redo menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem RedoMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 201,
               Command = ApplicationCommands.Redo,
               Icon = MainMenuIcon.Repeat,
               ToolTip = "Redo (Ctrl+Y)"
            };
         }
      }

      /// <summary>
      /// Gets the highlight menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem HighlightMenuItem
      {
         get
         {
            var item = new PeterMainMenuItem
            {
               Priority = 300,
               ToolTip = "Change Code Highlighting",
               Icon = MainMenuIcon.Marker
            };

            foreach (var hd in HighlightingManager.Instance.HighlightingDefinitions.OrderBy (d => d.Name))
            {
               if (hd.Name == "XmlDoc") continue;
               item.Children.Add (new PeterMainMenuItem
                                     {
                                        Icon = GetHighlighterIcon (hd.Name),
                                        Title = hd.Name,
                                        Command = PeterInternalCommands.ChangeHighlighting,
                                        CommandParameter = hd.Name
                                     });
            }

            return item;
         }
      }

      /// <summary>
      /// Gets the format menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem FormatMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 301,
               Command = PeterInternalCommands.Format,
               ToolTip = "Format Indentation",
               Icon = MainMenuIcon.IndentRight
            };
         }
      }

      #endregion

      #region View

      /// <summary>
      /// Gets the show file explorer menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem FileExplorerMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 0,
               HeaderName = "view",
               Command = PeterApplicationCommands.ShowToolWindow,
               CommandParameter = PeterToolWindows.FileExplorer,
               ToolTip = "File Explorer",
               Icon = MainMenuIcon.Foldertree
            };
         }
      }

      /// <summary>
      /// Gets the show code explorer menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem CodeExplorerMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 1,
               HeaderName = "view",
               Command = PeterApplicationCommands.ShowToolWindow,
               CommandParameter = PeterToolWindows.CodeExplorer,
               ToolTip = "Code Explorer",
               Icon = MainMenuIcon.Braces
            };
         }
      }

      /// <summary>
      /// Gets the show output menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem OutputMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 2,
               HeaderName = "view",
               Command = PeterApplicationCommands.ShowToolWindow,
               CommandParameter = PeterToolWindows.Output,
               ToolTip = "Application Output",
               Icon = MainMenuIcon.Colocation
            };
         }
      }

      /// <summary>
      /// Gets the show terminal menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem TerminalMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 3,
               HeaderName = "view",
               Command = PeterApplicationCommands.ShowToolWindow,
               CommandParameter = PeterToolWindows.Terminal,
               ToolTip = "Run commands in a terminal",
               Icon = MainMenuIcon.Terminal
            };
         }
      }

      /// <summary>
      /// Gets the show terminal menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem WorkspaceMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 3,
               HeaderName = "view",
               Command = PeterApplicationCommands.ShowToolWindow,
               CommandParameter = PeterToolWindows.Workspace,
               ToolTip = "Workspace",
               Icon = MainMenuIcon.Linux
            };
         }
      }

      /// <summary>
      /// Gets the show web menu item.
      /// </summary>
      [Export (typeof (IMainMenuItem))]
      public IMainMenuItem WebMenuItem
      {
         get
         {
            return new PeterMainMenuItem
            {
               Priority = 3,
               HeaderName = "view",
               Command = PeterApplicationCommands.ShowWeb,
               ToolTip = "Web Browser",
               Icon = MainMenuIcon.Domain
            };
         }
      }

      #endregion

      #region Quick Access

      /// <summary>
      /// Gets the options menu item.
      /// </summary>
      [Export (typeof (IMainMenuQuickAccessItem))]
      public IMainMenuQuickAccessItem OptionsMenuItem
      {
         get
         {
            return new PeterQuickAccessItem
            {
               Priority = 1,
               Command = PeterApplicationCommands.ShowOptions,
               ToolTip = "View and Edit Options",
               Icon = MainMenuIcon.Cog
            };
         }
      }

      /// <summary>
      /// Gets the options menu item.
      /// </summary>
      [Export (typeof (IMainMenuQuickAccessItem))]
      public IMainMenuQuickAccessItem AboutMenuItem
      {
         get
         {
            return new PeterQuickAccessItem
            {
               Priority = 99,
               Command = PeterApplicationCommands.ShowAbout,
               ToolTip = "About Peter...",
               Icon = MainMenuIcon.QuestionSign
            };
         }
      }

      #endregion

      #region Utility Methods

      /// <summary>
      /// Sets up the recent file list.
      /// </summary>
      public static void SetRecentFileCollection ()
      {
         s_RecentFiles.Children.Clear ();
         foreach (var recentFile in Settings.Default.RecentFiles)
         {
            var file = new FileInfo (recentFile);
            s_RecentFiles.Children.Add (new PeterMainMenuItem
            {
               Icon = MainMenuIconConverter.GetIconForFile (file),
               Title = file.Name,
               ToolTip = file.FullName,
               CommandParameter = file,
               Command = PeterApplicationCommands.OpenFile
            });
         }
      }

      /// <summary>
      /// Checks to see if the given file is in the recent file menu items, and adds it if not found.
      /// </summary>
      /// <param name="file">File to check.</param>
      public static void CheckForRecentFile (FileInfo file)
      {
         var item = s_RecentFiles.Children.FirstOrDefault (mi => mi.ToolTip == file.FullName);
         if (item == null)
         {
            s_RecentFiles.Children.Insert (0, new PeterMainMenuItem
            {
               Icon = MainMenuIconConverter.GetIconForFile (file),
               Title = file.Name,
               ToolTip = file.FullName,
               CommandParameter = file,
               Command = PeterApplicationCommands.OpenFile
            });
         }
         else
         {
            s_RecentFiles.Children.Remove (item);
            s_RecentFiles.Children.Insert (0, item);
         }

         while (s_RecentFiles.Children.Count > Settings.Default.MaxRecentFiles)
            s_RecentFiles.Children.RemoveAt (Settings.Default.MaxRecentFiles);
      }

      /// <summary>
      /// Gets the highlighter icon for the given name.
      /// </summary>
      /// <param name="name">Name of highlighter to get name for.</param>
      /// <returns>An icon for the highlighter.</returns>
      private static MainMenuIcon GetHighlighterIcon (string name)
      {
         switch (name.ToLower ())
         {
            case "ruby":
               return MainMenuIcon.Ruby;
            case "c#":
               return MainMenuIcon.Csharp;
            case "c++":
               return MainMenuIcon.Cplusplus;
            case "java":
               return MainMenuIcon.Java;
            case "javascript":
               return MainMenuIcon.Script;
            case "css":
               return MainMenuIcon.Scriptalt;
            case "html":
            case "asp/xhtml":
            case "c#/razor":
               return MainMenuIcon.Htmlfile;
            case "xml":
               return MainMenuIcon.Html;
            case "boo":
               return MainMenuIcon.Ghost;
            case "php":
               return MainMenuIcon.Php;
            case "powershell":
               return MainMenuIcon.Ssh;
            case "batchfile":
               return MainMenuIcon.Terminal;
            default:
               return MainMenuIcon.Marker;
         }
      }
      #endregion
   }
}
